﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Strive.DataAccess;
using Strive.Util.Text;
using HUBS1.HCMS.Entity;
using HUBS1.HCMS.Bll;
using HUBS1.HCMS.Bll.baseinfo;
using HCMS.Utility;
using System.Reflection;
using HUBS1.HCMS.Entity.OTA;
using HUBS1.HCMS.Provider;

namespace HUBS1.HCMS.BO
{
    public class OTABO : BaseBOBean
    {
        #region IOTABO Members
        #region OTA_HotelAvail
        public TMEX.Schemas.Response.TrCode100001.OTA_HotelAvailRS OTAHotelAvail(TMEX.Schemas.Request.TrCode100001.OTA_HotelAvailRQ Rq_HotelAvail)
        {

            ICacheManager hotelavailCacheManager = CacheFactory.GetCacheManager("HotelAvailRSCache");
            string hotelavailrskey = "";
            HCRS_HotelAvailRQ hotelavailrq = new HCRS_HotelAvailRQ();
            #region 校验
            string ota_ErrorCode = "";
            if (string.IsNullOrEmpty(Rq_HotelAvail.AvailRequestSegments.AvailRequestSegment[0].HotelSearchCriteria.Criterion[0].HotelRef[0].HotelCode))
                ota_ErrorCode += "361,";
            #endregion

            #region 获取信息
            if (ota_ErrorCode == "")
            {
                try
                {
                    hotelavailrq.PropID = Rq_HotelAvail.AvailRequestSegments.AvailRequestSegment[0].HotelSearchCriteria.Criterion[0].HotelRef[0].HotelCode;
                    hotelavailrq.UserID = int.Parse(Rq_HotelAvail.POS[0].RequestorID.ID);
                    if (Rq_HotelAvail.AvailRequestSegments.AvailRequestSegment[0].HotelSearchCriteria.AvailableOnlyIndicator != null)//是否返回不可用房型|Ture：只显示可用False：都显示
                        hotelavailrq.AvailableOnly = Rq_HotelAvail.AvailRequestSegments.AvailRequestSegment[0].HotelSearchCriteria.AvailableOnlyIndicator;
                    else
                        hotelavailrq.AvailableOnly = true;
                    if (Rq_HotelAvail.POS[0].BookingChannel.Type != null)
                        hotelavailrq.Channel = Rq_HotelAvail.POS[0].BookingChannel.Type;
                    else
                        hotelavailrq.Channel = "Website";
                    hotelavailrq.LanguageType = Rq_HotelAvail.PrimaryLangID;
                    foreach (TMEX.Schemas.Request.TrCode100001.AvailRequestSegmentsTypeAvailRequestSegment rqSet in Rq_HotelAvail.AvailRequestSegments.AvailRequestSegment)
                    {
                        HCRS_HotelAvailRQStay stayinfo = new HCRS_HotelAvailRQStay();
                        string stay_adult = rqSet.HotelSearchCriteria.Criterion[0].RoomStayCandidates[0].GuestCounts.GuestCount[0].Count;
                        if (!Function.IsSignlessInt(stay_adult))
                        {
                            ota_ErrorCode += "397,";
                            break;
                        }
                        stayinfo.Adults = int.Parse(stay_adult);

                        stayinfo.Children = 0;
                        string stay_data = rqSet.HotelSearchCriteria.Criterion[0].StayDateRange.Start;
                        if (string.IsNullOrEmpty(stay_data) || !Function.IsDate(stay_data))
                        {
                            ota_ErrorCode += "381,";
                            break;
                        }
                        stayinfo.Stay_Date = stay_data;

                        string stay_night = rqSet.HotelSearchCriteria.Criterion[0].StayDateRange.Duration;
                        if (!Function.IsSignlessInt(stay_night))
                        {
                            ota_ErrorCode += "362,";
                            break;
                        }
                        stayinfo.Nights = int.Parse(stay_night);

                        string stay_room = rqSet.HotelSearchCriteria.Criterion[0].RoomStayCandidates[0].Quantity;
                        if (!Function.IsSignlessInt(stay_room))
                        {
                            ota_ErrorCode += "363,";
                            break;
                        }
                        stayinfo.Rooms = int.Parse(stay_room);
                        stayinfo.Roomcode = rqSet.HotelSearchCriteria.Criterion[0].RoomStayCandidates[0].RoomTypeCode;
                        stayinfo.Rateclass = rqSet.HotelSearchCriteria.Criterion[0].RatePlanCandidates[0].RatePlanCode;
                        hotelavailrq.HotelAvailStay.Add(stayinfo);
                        hotelavailrskey = Rq_HotelAvail.POS[0].RequestorID.ID + Rq_HotelAvail.AvailRequestSegments.AvailRequestSegment[0].HotelSearchCriteria.Criterion[0].HotelRef[0].HotelCode + stay_adult + stay_data + stay_night + stay_room + rqSet.HotelSearchCriteria.Criterion[0].RatePlanCandidates[0].RatePlanCode;
                    }
                }
                catch (Exception ex)
                {
                    ota_ErrorCode += ex.Message + ",";
                }
            }
            #endregion

            TMEX.Schemas.Response.TrCode100001.OTA_HotelAvailRS ota_rs = new TMEX.Schemas.Response.TrCode100001.OTA_HotelAvailRS();
            if ((TMEX.Schemas.Response.TrCode100001.OTA_HotelAvailRS)hotelavailCacheManager.GetData(hotelavailrskey)!=null)
                ota_rs = (TMEX.Schemas.Response.TrCode100001.OTA_HotelAvailRS)hotelavailCacheManager.GetData(hotelavailrskey);
            else
            {
                ota_rs.Items = new object[5];
                try
                {
                    if (ota_ErrorCode == "")
                    {
                        HCRS_HotelAvailRS hotelavailrs = new HCRS_HotelAvailRS();
                        HotelAvail _hotelavail = new HotelAvail();
                        _hotelavail.QueryHotelAvail(hotelavailrq, out hotelavailrs, out ota_ErrorCode);

                        if (ota_ErrorCode == "")
                        {
                            #region Response Correct Data
                            TMEX.Schemas.Response.TrCode100001.SuccessType success = new TMEX.Schemas.Response.TrCode100001.SuccessType();
                            ota_rs.Items[0] = success;
                            TMEX.Schemas.Response.TrCode100001.OTA_HotelAvailRSRoomStays roomStays = new TMEX.Schemas.Response.TrCode100001.OTA_HotelAvailRSRoomStays();
                            roomStays.RoomStay = new TMEX.Schemas.Response.TrCode100001.OTA_HotelAvailRSRoomStaysRoomStay[rsInfo.RateMap.RatedataList.Count];
                            int i = 0;
                            foreach (TMEX.Entity.FOGXML.GetRateMap.RSRatedataInfo rateInfo in rsInfo.RateMap.RatedataList)
                            {
                                TMEX.Schemas.Response.TrCode100001.OTA_HotelAvailRSRoomStaysRoomStay ota_roomStayType = new TMEX.Schemas.Response.TrCode100001.OTA_HotelAvailRSRoomStaysRoomStay();

                                ota_roomStayType.RatePlans = new TMEX.Schemas.Response.TrCode100001.RatePlanType[1];
                                TMEX.Schemas.Response.TrCode100001.RatePlanType ratePlanType = new TMEX.Schemas.Response.TrCode100001.RatePlanType();
                                ota_roomStayType.RatePlans[0] = ratePlanType;

                                ota_roomStayType.RoomTypes = new TMEX.Schemas.Response.TrCode100001.RoomTypeType[1];
                                TMEX.Schemas.Response.TrCode100001.RoomTypeType roomType = new TMEX.Schemas.Response.TrCode100001.RoomTypeType();
                                ota_roomStayType.RoomTypes[0] = roomType;

                                ratePlanType.CancelPenalties = new TMEX.Schemas.Response.TrCode100001.CancelPenaltiesType();
                                ratePlanType.CancelPenalties.CancelPenalty = new TMEX.Schemas.Response.TrCode100001.CancelPenaltyType[1];
                                TMEX.Schemas.Response.TrCode100001.CancelPenaltyType cancelPenaltyType = new TMEX.Schemas.Response.TrCode100001.CancelPenaltyType();
                                ratePlanType.CancelPenalties.CancelPenalty[0] = cancelPenaltyType;

                                cancelPenaltyType.PolicyCode = rateInfo.Ratedetail[0].CXL;


                                ratePlanType.Guarantee = new TMEX.Schemas.Response.TrCode100001.GuaranteeType[1];
                                TMEX.Schemas.Response.TrCode100001.GuaranteeType guarantee = new TMEX.Schemas.Response.TrCode100001.GuaranteeType();
                                ratePlanType.Guarantee[0] = guarantee;
                                guarantee.GuaranteeCode = rateInfo.Ratedetail[0].GUA;

                                roomType.RoomTypeCode = rateInfo.Plandetail.Room;
                                ota_roomStayType.RoomStayStatus = rateInfo.Plandetail.Status;
                                ratePlanType.RatePlanName = rateInfo.Plandetail.name;
                                ota_roomStayType.BasicPropertyInfo = new TMEX.Schemas.Response.TrCode100001.BasicPropertyInfoType();
                                ota_roomStayType.BasicPropertyInfo.HotelCode = rateInfo.Plandetail.prop;


                                TMEX.Schemas.Response.TrCode100001.FormattedTextTextType text_roomtypeDes = new TMEX.Schemas.Response.TrCode100001.FormattedTextTextType();
                                text_roomtypeDes.Value = rateInfo.Plandetail.roomtype.Desc1;
                                roomType.RoomDescription = new TMEX.Schemas.Response.TrCode100001.ParagraphType();
                                roomType.RoomDescription.ItemsElementName = new TMEX.Schemas.Response.TrCode100001.ItemsChoiceType[1];
                                roomType.RoomDescription.ItemsElementName[0] = TMEX.Schemas.Response.TrCode100001.ItemsChoiceType.Text;
                                roomType.RoomDescription.Items = new object[1];
                                roomType.RoomDescription.Items[0] = text_roomtypeDes;

                                roomType.RoomType = rateInfo.Plandetail.roomtype.name;


                                TMEX.Schemas.Response.TrCode100001.FormattedTextTextType text_rateclassDes = new TMEX.Schemas.Response.TrCode100001.FormattedTextTextType();
                                text_rateclassDes.Value = rateInfo.Plandetail.rateclass.Desc1;
                                ratePlanType.RatePlanDescription = new TMEX.Schemas.Response.TrCode100001.ParagraphType();
                                ratePlanType.RatePlanDescription.ItemsElementName = new TMEX.Schemas.Response.TrCode100001.ItemsChoiceType[1];
                                ratePlanType.RatePlanDescription.ItemsElementName[0] = TMEX.Schemas.Response.TrCode100001.ItemsChoiceType.Text;
                                ratePlanType.RatePlanDescription.Items = new object[1];
                                ratePlanType.RatePlanDescription.Items[0] = text_rateclassDes;

                                ota_roomStayType.RoomRates = new TMEX.Schemas.Response.TrCode100001.RoomStayTypeRoomRates();
                                ota_roomStayType.RoomRates.RoomRate = new TMEX.Schemas.Response.TrCode100001.RoomStayTypeRoomRatesRoomRate[rateInfo.Ratedetail.Count];
                                int j = 0;
                                foreach (TMEX.Entity.FOGXML.GetRateMap.RSRatedetailInfo ratedetail in rateInfo.Ratedetail)
                                {
                                    TMEX.Schemas.Response.TrCode100001.RoomStayTypeRoomRatesRoomRate ota_roomrate = new TMEX.Schemas.Response.TrCode100001.RoomStayTypeRoomRatesRoomRate();

                                    ota_roomrate.Availability = new TMEX.Schemas.Response.TrCode100001.RoomRateTypeAvailability[1];
                                    TMEX.Schemas.Response.TrCode100001.RoomRateTypeAvailability availability = new TMEX.Schemas.Response.TrCode100001.RoomRateTypeAvailability();
                                    ota_roomrate.Availability[0] = availability;
                                    switch (ratedetail.AvStat)
                                    {
                                        //可用
                                        case "A":
                                            availability.AvailabilityStatus = TMEX.Schemas.Response.TrCode100001.RateIndicatorType.AvailableForSale;
                                            break;
                                        //停滞(关房)
                                        case "B":
                                            availability.AvailabilityStatus = TMEX.Schemas.Response.TrCode100001.RateIndicatorType.RoomTypeClosed;
                                            break;
                                        //限制入住天数
                                        case "L":
                                            availability.AvailabilityStatus = TMEX.Schemas.Response.TrCode100001.RateIndicatorType.LOS_Restricted;
                                            break;
                                        //限制当天入住
                                        case "C":
                                            availability.AvailabilityStatus = TMEX.Schemas.Response.TrCode100001.RateIndicatorType.LimitedAvailability;
                                            break;
                                        default:
                                            availability.AvailabilityStatus = TMEX.Schemas.Response.TrCode100001.RateIndicatorType.UnableToProcess;
                                            break;

                                    }
                                    ota_roomrate.Rates = new TMEX.Schemas.Response.TrCode100001.RateTypeRate[1];
                                    TMEX.Schemas.Response.TrCode100001.RateTypeRate roomrate_rate = new TMEX.Schemas.Response.TrCode100001.RateTypeRate();
                                    ota_roomrate.Rates[0] = roomrate_rate;
                                    roomrate_rate.MaxLOS = ratedetail.MaxLOS;
                                    roomrate_rate.MinLOS = ratedetail.MinLOS;
                                    roomrate_rate.NumberOfUnits = ratedetail.Allotment;
                                    //每日价
                                    roomrate_rate.Base = new TMEX.Schemas.Response.TrCode100001.TotalType();
                                    roomrate_rate.Base.CurrencyCode = "CNY";
                                    roomrate_rate.Base.AmountBeforeTaxSpecified = true;
                                    //decimal decTotal = 0;
                                    //decimal.TryParse(ratedetail.Total, out decTotal);
                                    //roomrate_rate.Base.AmountBeforeTax = decTotal;
                                    roomrate_rate.Base.AmountBeforeTax = decimal.Parse(ratedetail.Total);
                                    roomrate_rate.EffectiveDate = DateTime.Parse(ratedetail.date);
                                    roomrate_rate.EffectiveDateSpecified = true;
                                    ota_roomrate.Total = new TMEX.Schemas.Response.TrCode100001.TotalType();
                                    ota_roomrate.Total.AmountBeforeTax = decimal.Parse(ratedetail.Total);
                                    ota_roomrate.RatePlanCode = rateInfo.Plandetail.Rate;

                                    TMEX.Schemas.Response.TrCode100001.FormattedTextTextType text_roomrateDes = new TMEX.Schemas.Response.TrCode100001.FormattedTextTextType();
                                    text_roomrateDes.Value = rateInfo.Plandetail.Description;
                                    ota_roomrate.RoomRateDescription = new TMEX.Schemas.Response.TrCode100001.ParagraphType[1];
                                    TMEX.Schemas.Response.TrCode100001.ParagraphType paraType = new TMEX.Schemas.Response.TrCode100001.ParagraphType();
                                    paraType.ItemsElementName = new TMEX.Schemas.Response.TrCode100001.ItemsChoiceType[1];
                                    paraType.ItemsElementName[0] = TMEX.Schemas.Response.TrCode100001.ItemsChoiceType.Text;
                                    ota_roomrate.RoomRateDescription[0] = paraType;
                                    paraType.Items = new object[1];
                                    paraType.Items[0] = text_roomrateDes;

                                    ota_roomStayType.RoomRates.RoomRate[j] = ota_roomrate;
                                    j++;
                                }
                                roomStays.RoomStay[i] = ota_roomStayType;
                                i++;
                            }
                            ota_rs.Items[1] = roomStays;
                            #endregion
                        }
                    }
                }
                catch (Exception ex)
                {
                    ota_ErrorCode += ex.Message + ",";
                }

                #region ErrorCode
                //错误代吗
                if (ota_ErrorCode != "")
                {
                    string errortext = "";
                    errortext += XmlSerializer<TMEX.Schemas.Request.TrCode100001.OTA_HotelAvailRQ>.Xml.Serialize(Rq_HotelAvail).Replace("<", "&lt;").Replace(">", "&gt;") + "<br>";
                    ota_ErrorCode = ota_ErrorCode.TrimEnd(',');
                    string[] arrerrorcode = ota_ErrorCode.Split(',');
                    TMEX.Schemas.Response.TrCode100001.ErrorsType errorList = new TMEX.Schemas.Response.TrCode100001.ErrorsType();
                    errorList.Error = new TMEX.Schemas.Response.TrCode100001.ErrorType[arrerrorcode.Length];
                    for (int e = 0; e < arrerrorcode.Length; e++)
                    {
                        TMEX.Schemas.Response.TrCode100001.ErrorType error = new TMEX.Schemas.Response.TrCode100001.ErrorType();
                        error.Code = arrerrorcode[e];
                        error.ShortText = TMEX.Common.Function.GetErrorText(arrerrorcode[e], 0);
                        error.Value = TMEX.Common.Function.GetErrorText(arrerrorcode[e], 1);
                        errortext += error.Code + "[" + error.ShortText + "]<br>";
                        errorList.Error[e] = error;
                    }
                    ota_rs.Items[0] = errorList;
                    Function.SendErrorMail(errortext, "OTA_HotelAvail接口错误");
                }
                #endregion

                hotelavailCacheManager.Add(hotelavailrskey, ota_rs, CacheItemPriority.Normal, null, new AbsoluteTime(DateTime.Now.AddMinutes(3)));
            }
            return ota_rs;
        }
        #endregion
        #endregion
    }
}